
#include <iostream>
#include <memory>

using namespace std;

template<class T>
struct Delete
{
    void operator()(T* ptr)
    {
        cout << "Delete:" << ptr << endl;
        delete ptr;
    }
};

template<class T>
struct DeleteArray
{
    void operator()(T* ptr)
    {
        cout << "DeleteArray:" << ptr << endl;
        delete[] ptr;
    }
};

#include "UniquePtr.h"
#include "SharePtr.h"
#include "WeakPtr.h"
#include "AutoPtr.h"

class A
{
public:
    A() {}

    ~A()
    {
        cout << "delete ~A()" << endl;
    }

    void Print()
    {
        cout << a << ' ' << b << endl;
    }

    int a = 0;
    int b = 0;
};

// 1. RAII
// 2. 像指针一样
// 3. 拷贝问题：可以有很多方案
template<class T> class Smart_Ptr
{
public:
    Smart_Ptr(T* ptr = nullptr)
        :_ptr(ptr)
    {}

    ~Smart_Ptr()
    {
        if (_ptr)
        {
            cout << "delete" << ':' << _ptr << endl;
            delete _ptr;
        }
    }

    T& operator*() { return *_ptr; }
    T* operator->() { return _ptr; }

private:
    T* _ptr;
};
// 拷贝是值拷贝，会出现问题，释放两次

void test3()
{
    A* pa1 = new A;
    pa1->Print();
    Smart_Ptr<A> ptr1(pa1);
    ptr1->a = 100, ptr1->b = 200;
    ptr1->Print();
}

//void test1()
//{
//    auto_ptr<A> ptr1(new A);
//
//    ptr1->a ++ ;
//    ptr1->b ++ ;
//
//    ptr1->Print();
//}
//
//void test2()
//{
//    A* pa = new A;
//    pa->Print();
//    shared_ptr<A> ptr1(pa);
//    ptr1->a = 10;
//    ptr1->b = 20;
//    ptr1->Print();
//
//    shared_ptr<A> ptr2 = ptr1;
//    ptr2->Print();
//    shared_ptr<A> ptr3(ptr2);
//    ptr3->Print();
//
//    A* pa2 = new A;
//    pa2->Print();
//    pa2->a = 100, pa2->b = 200;
//    pa2->Print();
//
//    shared_ptr<A> ptr1(pa2);
//    
//}

void testUniquePtr()
{

    My::unique_ptr<A> ptr(new A);
    ptr->Print();
    ptr->a = 100, ptr->b = 200;
    ptr->Print();
}

int main()
{
    //test1();
    //test2();
    //test3();

    testUniquePtr();

    return 0;
}
